﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Controls.Shapes;
using Microsoft.Win32;
using Path = System.IO.Path;

namespace AvalonAdmin.Helpers
{
    /// <summary>
    /// 雷电模拟器操作
    /// </summary>
    public class LDProxyHelper
    {

        #region 获取雷电模拟器的EXE和安装模拟器的EXE

        /// <summary>
        /// 模拟器命令的路径
        /// </summary>
        private readonly string _ldConsolePath;

        /// <summary>
        /// adb命令的路径
        /// </summary>
        private readonly string _adbConsolePath;

        public LDProxyHelper()
        {
            // 方法一：通过进程获取
            string pathFromProcess = GetLDPlayerPath();

            // 方法二：通过注册表获取
            string pathFromRegistry = GetLDPlayerPathFromRegistry();

            // 方法三：通过默认路径获取
            string defaultPath = FindLDPlayerPath();

            // 综合判断最优路径
            string finalPath = pathFromProcess ?? pathFromRegistry ?? defaultPath;

            _ldConsolePath = Path.Combine(finalPath, "ldconsole.exe");
            _adbConsolePath = Path.Combine(finalPath, "adb.exe");

            if (File.Exists(_ldConsolePath))
            {
                // 获取文件版本信息
                var ldVersionInfo = FileVersionInfo.GetVersionInfo(_ldConsolePath);
                var adbVersionInfo = FileVersionInfo.GetVersionInfo(_adbConsolePath);
                return; // 找到文件，直接返回
            }
            else
            {
                throw new FileNotFoundException("雷电模拟器控制台程序未找到", _ldConsolePath);
            }
        }

        /// <summary>
        /// 通过进程信息获取雷电模拟器路径
        /// </summary>
        /// <returns></returns>
        public string GetLDPlayerPath()
        {
            // 查找雷电模拟器主进程
            Process[] ldProcesses = Process.GetProcessesByName("dnplayer");

            if (ldProcesses == null || ldProcesses.Length == 0)
            {
                ldProcesses = Process.GetProcessesByName("LdVBoxHeadless"); // 备用进程名

                if (ldProcesses == null || ldProcesses.Length == 0)
                {
                    ldProcesses = Process.GetProcessesByName("dnmultiplayer"); // 备用进程名
                }
            }


            if (ldProcesses.Length > 0)
            {
                try
                {
                    string mainModulePath = ldProcesses[0].MainModule.FileName;
                    string directory = Path.GetDirectoryName(mainModulePath);
                    return directory;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"无法获取进程路径: {ex.Message}");
                }
            }

            return null;
        }

        /// <summary>
        /// 通过注册表查找安装路径
        /// </summary>
        /// <returns></returns>
        public string GetLDPlayerPathFromRegistry()
        {
            // 32位系统或64位系统下的32位应用注册表路径
            string registryPath = @"SOFTWARE\leidian\LDPlayer";
            // 64位系统下的64位应用注册表路径
            string registryPath64 = @"SOFTWARE\WOW6432Node\leidian\LDPlayer";

            string installPath = GetInstallPathFromRegistry(registryPath) ??
                                GetInstallPathFromRegistry(registryPath64);

            return installPath;
        }

        private string GetInstallPathFromRegistry(string path)
        {
            try
            {
                using (RegistryKey key = Registry.LocalMachine.OpenSubKey(path))
                {
                    if (key != null)
                    {
                        object value = key.GetValue("InstallDir");
                        if (value != null)
                        {
                            return value.ToString();
                        }
                    }
                }
            }
            catch
            {
                // 忽略访问错误
            }
            return null;
        }

        /// <summary>
        /// 通过默认安装路径查找
        /// </summary>
        /// <returns></returns>
        public string FindLDPlayerPath()
        {
            foreach (var path in GetPossibleDefaultPaths())
            {
                if (Directory.Exists(path) && File.Exists(Path.Combine(path, "dnplayer.exe")))
                {
                    return path;
                }
            }
            return null;
        }

        private string[] GetPossibleDefaultPaths()
        {
            return new string[]
            {
            @"C:\Program Files\LDPlayer\LDPlayer",
            @"C:\Program Files\LDPlayer\LDPlayer9",
            @"C:\Program Files (x86)\LDPlayer\LDPlayer",
            @"C:\Program Files (x86)\LDPlayer\LDPlayer9",
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "LDPlayer", "LDPlayer"),
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "LDPlayer", "LDPlayer9"),
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "LDPlayer", "LDPlayer"),
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "LDPlayer", "LDPlayer9")
            };
        }

        #endregion

        #region 获取模拟器多开器的模拟器列表
        /// <summary>
        /// 获取所有模拟器信息
        /// 获取的列表如下：
        /// 0,雷电模拟器,11015390,25954006,1,45488,58504,720,1280,320
        /// 1,雷电模拟器-1,9179734,988868,1,24408,75452,720,1280,320
        /// 2,雷电模拟器-2,0,0,0,-1,-1,720,1280,320
        /// 3,雷电模拟器-3,0,0,0,-1,-1,720,1280,320 
        /// 99999,电脑桌面,0,0,1,0,0,1151,720,0
        /// 位置  	字段值示例	    含义
        /// 0	    0	            模拟器索引号(从0开始)
        /// 1	    雷电模拟器       模拟器名称
        /// 2	    11015390	    模拟器唯一标识符(设备ID)
        /// 3	    25954006	    进程ID(PID)
        /// 4	    1	            运行状态(0=未运行, 1=运行中)
        /// 5	    45488	        VBox进程ID
        /// 6	    58504	        ADB端口号
        /// 7	    720	            屏幕分辨率-高度
        /// 8	    1280	        屏幕分辨率-宽度
        /// 9	    320	            DPI设置
        /// </summary>
        public async Task<List<LDMultiPlayerInfo>> GetAllEmulatorsFixed()
        {
            var emulators = new List<LDMultiPlayerInfo>();
            try
            {
                // 尝试list2命令
                string output = await ExecuteCommand("list2", _ldConsolePath);
                if (!string.IsNullOrEmpty(output)) // 排除无效响应
                {
                    ParseList2Output(output, emulators);
                }
            }
            catch { /* 忽略错误 */ }
            return emulators;
        }

        /// <summary>
        /// 解析list2命令输出
        /// </summary>
        private void ParseList2Output(string output, List<LDMultiPlayerInfo> emulators)
        {
            foreach (var line in output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
            {
                if (string.IsNullOrWhiteSpace(line) || line.StartsWith("index") || line.StartsWith("99999"))
                    continue;

                // 改进分隔符处理，兼容不同雷电版本
                var parts = line.Split(new[] { ',', ';', '\t' }, StringSplitOptions.RemoveEmptyEntries);

                if (parts.Length >= 6)
                {
                    emulators.Add(new LDMultiPlayerInfo
                    {
                        Index = int.Parse(parts[0].Trim()),
                        Name = parts[1].Trim(),
                        UUID = parts[2].Trim(),
                        ProcessId = int.Parse(parts[3].Trim()),
                        Status = parts[4].Trim().Equals("1", StringComparison.Ordinal) ? "Running" : "Stopped",
                        VBoxProcessId = parts[5].Trim(),
                        AdbPort = parts[6].Trim(),
                        Height = parts[7].Trim(),
                        Width = parts[8].Trim(),
                        DPI = parts[9].Trim(),
                    });
                }
            }
        }

        #endregion

        #region 设置模拟器代理IP

        /// <summary>
        /// 为模拟器配置代理
        /// </summary>
        /// <param name="emulatorIndex"></param>
        /// <param name="proxy"></param>
        /// <returns></returns>
        public async Task<bool> SetProxy(int emulatorIndex, ProxyInfo proxy)
        {
            try
            {
                if (proxy.ExpireDate < DateTime.Now)
                {
                    Console.WriteLine($"代理已过期: {proxy.IP}:{proxy.Port} 过期时间: {proxy.ExpireDate}");
                    return false;
                }

                await ExecuteCommand($"quit --index {emulatorIndex}", _ldConsolePath);
                // 设置代理地址和端口
                var authArgs = !string.IsNullOrEmpty(proxy.Username) ? $"--proxy-user {proxy.Username} --proxy-pwd {proxy.Password}" : "";
                var arguments = $"modify --index {emulatorIndex} --proxy {proxy.IP}:{proxy.Port} --proxytype {proxy.Proxytype.ToLower()} {authArgs}";
                await ExecuteCommand(arguments, _ldConsolePath);
                await ExecuteCommand($"modify --index {emulatorIndex} --save", _ldConsolePath);
                // 重启模拟器使设置生效
                await Task.Delay(20000);
                await ExecuteCommand($"launch --index {emulatorIndex}", _ldConsolePath);

                Console.WriteLine($"成功为模拟器{emulatorIndex}设置代理: {proxy.Region} {proxy.IP}:{proxy.Port}");
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"为模拟器{emulatorIndex}设置代理失败: {ex.Message}");
                return false;
            }
        }

        #endregion

        #region 获取模拟器的IP
        /// <summary>
        /// 获取模拟器的IP
        /// </summary>
        /// <param name="index">模拟器序号</param>
        /// <returns></returns>
        public async Task<string> GetEmulatorIpFromProperties(int index)
        {
            var output = await ExecuteCommand($"runninglist --index {index}", _ldConsolePath);

            // 优先查找 eth0 网卡IP
            if (output.Contains("eth0"))
            {
                string eth0Section = output.Substring(output.IndexOf("eth0"));
                if (eth0Section.Contains("inet addr:"))
                {
                    int start = eth0Section.IndexOf("inet addr:") + 10;
                    int end = eth0Section.IndexOf(" ", start);
                    return eth0Section.Substring(start, end - start);
                }
            }

            // 查找任何网卡的IP
            if (output.Contains("inet addr:"))
            {
                int start = output.IndexOf("inet addr:") + 10;
                int end = output.IndexOf(" ", start);
                return output.Substring(start, end - start);
            }

            // 新版模拟器可能使用 ip addr 命令格式
            if (output.Contains("inet "))
            {
                foreach (var line in output.Split('\n'))
                {
                    if (line.Contains("inet ") && !line.Contains("127.0.0.1"))
                    {
                        var parts = line.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        if (parts.Length > 1)
                        {
                            return parts[1].Split('/')[0];
                        }
                    }
                }
            }

            return "10.0.2.15"; // 雷电模拟器默认IP
        }
        #endregion

        /// <summary>
        /// 批量配置多开代理
        /// </summary>
        /// <param name="proxies"></param>
        public async Task BatchSetProxies(List<ProxyInfo> proxies)
        {
            int successCount = 0;

            for (int i = 0; i < proxies.Count; i++)
            {
                if (await SetProxy(i, proxies[i]))
                {
                    successCount++;
                }

                // 避免操作太快导致问题
                await Task.Delay(100);
            }

            Console.WriteLine($"代理配置完成，成功配置{successCount}个，失败{proxies.Count - successCount}个");
        }

        /// <summary>
        /// 重启模拟器
        /// </summary>
        /// <param name="index"></param>

        private async void RestartEmulator(int emulatorIndex)
        {
            await ExecuteCommand($"quit --index {emulatorIndex}", _ldConsolePath);
            System.Threading.Thread.Sleep(5000);
            await ExecuteCommand($"launch --index {emulatorIndex}", _ldConsolePath);
        }

        #region 执行模拟器命令
        /// <summary>
        /// 执行模拟器命令
        /// </summary>
        /// <param name="arguments"></param>
        /// <returns></returns>
        private async Task<string> ExecuteCommand(string arguments, string exePath)
        {
            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = exePath,
                    WorkingDirectory = Path.GetDirectoryName(exePath), // 关键设置
                    Arguments = arguments,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow = true
                }
            };

            process.Start();
            var output = await process.StandardOutput.ReadToEndAsync();
            await process.WaitForExitAsync();

            return output;
        }
        #endregion

    }

    public class ProxyInfo
    {
        /// <summary>
        /// 代理IP地址
        /// </summary>
        public string IP { get; set; }
        /// <summary>
        /// 代理IP端口
        /// </summary>
        public int Port { get; set; }
        /// <summary>
        /// 设置代理认证的用户名
        /// </summary>
        public string Username { get; set; }
        /// <summary>
        /// 设置代理认证的密码
        /// </summary>
        public string Password { get; set; }
        /// <summary>
        /// 代理过期时间
        /// </summary>
        public DateTime ExpireDate { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string Region { get; set; }

        /// <summary>
        /// 代理类型：
        /// http (HTTP代理)
        /// socks4(SOCKS4代理)
        /// socks5(socks5代理)
        /// </summary>
        public string Proxytype { get; set; }

        //public static ProxyInfo Parse(string line)
        //{
        //    var parts = line.Split('|');
        //    if (parts.Length < 6) throw new FormatException("代理IP格式不正确");

        //    return new ProxyInfo
        //    {
        //        IP = parts[0].Trim(),
        //        Port = int.Parse(parts[1].Trim()),
        //        Username = parts[2].Trim(),
        //        Password = parts[3].Trim(),
        //        ExpireDate = DateTime.Parse(parts[4].Trim()),
        //        Region = parts[5].Trim(),
        //        Proxytype = parts[6].Trim()
        //    };
        //}
    }

    /// <summary>
    /// 模拟器信息
    /// </summary>
    public class LDMultiPlayerInfo
    {
        /// <summary>
        /// 模拟器索引号(从0开始)
        /// </summary>
        public int Index { get; set; }
        /// <summary>
        /// 模拟器名称
        /// </summary>
        public string? Name { get; set; }
        /// <summary>
        /// 模拟器唯一标识符(设备ID)
        /// </summary>
        public string? UUID { get; set; }
        /// <summary>
        /// 进程ID(PID)
        /// </summary>
        public int? ProcessId { get; set; }
        /// <summary>
        /// 运行状态(0=未运行, 1=运行中)
        /// </summary>
        public string? Status { get; set; }
        /// <summary>
        /// VBox进程ID
        /// </summary>
        public string VBoxProcessId { get; set; }
        /// <summary>
        /// ADB端口号
        /// </summary>
        public string AdbPort { get; set; }
        /// <summary>
        /// 屏幕分辨率-高度
        /// </summary>
        public string Height { get; set; }
        /// <summary>
        /// 屏幕分辨率-宽度
        /// </summary>
        public string Width { get; set; }
        /// <summary>
        /// DPI设置
        /// </summary>
        public string DPI { get; set; }
    }
}
